Skip to content

backlog: Otto-160 parser-tech directive — FParsec first, ANTLR fallback#338

Merged
AceHack merged 1 commit intomainfrom
backlog/otto-160-parser-tech-fparsec-first-antlr-fallback
Apr 24, 2026
Merged

backlog: Otto-160 parser-tech directive — FParsec first, ANTLR fallback#338
AceHack merged 1 commit intomainfrom
backlog/otto-160-parser-tech-fparsec-first-antlr-fallback

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 24, 2026

Summary

Binding ordering for external-language parser technology in Zeta per Aaron Otto-160 directive:

"maybe for sql and the other exernal languages and flavor/dialects we could use f# parser combinators, if that does not fit good then antlr, backlog"

  1. FParsec first. Stephan Tolksdorf's parser-combinator library — idiomatic F#, integrates with DU-based AST, no code-gen, no Java build-time dep.
  2. ANTLR fallback only when FParsec demonstrably fails (huge ambiguous grammars, deeply interlocking precedence, multi-MB query performance, left-recursion needing transforms).
  3. Hybrid across surfaces allowed (Cypher=ANTLR + signal=FParsec OK); forbidden within one surface (no mixed stacks for one DSL).
  4. Per-surface written justification required in design doc.

Captured cost distinction: ANTLR's build-time Java dependency (antlr4-tool.jar) is the main ergonomic friction; FParsec avoids it entirely.

Why this PR

Otto-160 directive. One row lands on its own branch to avoid positional-append conflict with PR #334 (pending merge, also touches the F# DSL row cluster).

Test plan

🤖 Generated with Claude Code

Aaron Otto-160: "maybe for sql and the other exernal languages
and flavor/dialects we could use f# parser combinators, if that
does not fit good then antlr, backlog"

Binding ordering for every external-language compatibility
surface Zeta ships (SQL / GQL / Cypher / Gremlin / SPARQL /
Datalog / PostgreSQL wire / MySQL wire / Esper EPL / Flink SQL /
Flux / PromQL / KQL etc):

1. Try FParsec (Stephan Tolksdorf's parser-combinator library).
   Idiomatic F#; integrates with DU-based AST; no code-gen; no
   Java build dependency; BSD license.

2. Fall back to ANTLR4 ONLY if FParsec demonstrably does not
   scale or fit:
   - very large ambiguous grammars (full SQL-92 + vendor)
   - performance-critical parsers on multi-MB queries
   - deeply interlocking precedence
   - left-recursive grammars needing transforms

Hybrid allowed across surfaces (Cypher=ANTLR + signal=FParsec
OK), forbidden within one surface.

Per-surface written justification required in design doc.

License + package notes captured: both are factory-compatible;
ANTLR carries a Java build-time dependency (antlr4-tool.jar)
that FParsec avoids — this is the main ergonomic cost when
choosing ANTLR.

Priority P1 post-v1-roadmap. Effort: S per surface justification.
Composes with the F# DSL row cluster (per-entry-point DSLs +
container DSL + LINQ-compatible entry points, currently in
PR #334 pending merge) and the pluggable wire-protocol row
below (natural first application).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 24, 2026 08:52
@AceHack AceHack enabled auto-merge (squash) April 24, 2026 08:52
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@AceHack AceHack merged commit 1b2df4b into main Apr 24, 2026
12 checks passed
@AceHack AceHack deleted the backlog/otto-160-parser-tech-fparsec-first-antlr-fallback branch April 24, 2026 08:53
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new BACKLOG entry capturing the Otto-160 directive that Zeta should prefer F# parser combinators (FParsec) for external-language/dialect surfaces, with ANTLR as a documented fallback.

Changes:

  • Adds a P1 BACKLOG row defining “FParsec first, ANTLR fallback” for external-language parser technology selection.
  • Documents per-surface decision/justification expectations (and forbids mixing parser stacks within a single DSL surface).

Comment thread docs/BACKLOG.md
Comment on lines +809 to +815
`Antlr4.Runtime.Standard` + a build-time `antlr4-
tool.jar` (the code-generator). The build-time Java
dependency of ANTLR is the key ergonomic cost — it
means `tools/setup/` must ensure a JDK is present,
and `Directory.Build.props` needs a custom target
that invokes antlr4-tool at pre-build. FParsec has
none of this cost — it is pure F#.
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inline code span for antlr4-tool.jar is split across two lines (antlr4- on one line, tool.jar on the next). In rendered Markdown this inserts whitespace/newline into the code span, so it won’t display as the intended filename. Keep the filename in a single inline code span on one line (or drop the backticks if it must wrap).

Suggested change
`Antlr4.Runtime.Standard` + a build-time `antlr4-
tool.jar` (the code-generator). The build-time Java
dependency of ANTLR is the key ergonomic cost — it
means `tools/setup/` must ensure a JDK is present,
and `Directory.Build.props` needs a custom target
that invokes antlr4-tool at pre-build. FParsec has
none of this cost — it is pure F#.
`Antlr4.Runtime.Standard` + a build-time `antlr4-tool.jar`
(the code-generator). The build-time Java dependency
of ANTLR is the key ergonomic cost — it means
`tools/setup/` must ensure a JDK is present, and
`Directory.Build.props` needs a custom target that
invokes antlr4-tool at pre-build. FParsec has none
of this cost — it is pure F#.

Copilot uses AI. Check for mistakes.
AceHack added a commit that referenced this pull request Apr 24, 2026
Addresses Amara 18th-ferry correction #6: PLV = 1 can mean
anti-phase locking, not same-time synchronization. Downstream
detectors that rely on "PLV = 1 => synchronized" misread
anti-phase coordinators as same-time coordinators.

Two new functions in `TemporalCoordinationDetection`:

- `meanPhaseOffset phasesA phasesB : double option`
  Returns the argument (angle) of the mean complex phase-
  difference vector whose magnitude is the PLV. Returns
  None when series are empty, mismatched-length, or when
  the mean vector has effectively zero magnitude (1e-12
  floor) — in which case direction is mathematically
  undefined.

- `phaseLockingWithOffset phasesA phasesB : struct (double * double) option`
  Returns both magnitude and offset in one sequence pass.
  Zero-magnitude case: magnitude near 0, offset = nan;
  near-zero magnitude is the caller's reliable "offset is
  undefined" signal.

Existing `phaseLockingValue` contract unchanged; new primitives
are additive. Downstream `Graph.coordinationRiskScore*` and any
other detector consuming PLV can now add a separate offset-
based term instead of collapsing both into one scalar (Amara's
explicit recommendation in correction #6).

8 new xUnit tests covering:
- Identical series (offset = 0)
- Constant pi/4 offset (observed = -pi/4, a-minus-b convention)
- Anti-phase series (magnitude 1, offset = pi) — the correction
  #6 regression test, contrasted against in-phase (offset 0)
  with identical magnitude
- Uniformly-distributed differences (zero-magnitude => None)
- Empty / mismatched-length / single-element edge cases
- phaseLockingWithOffset magnitude matches phaseLockingValue
  (consistency property preventing silent detector divergence)
- phaseLockingWithOffset zero-magnitude returns (near-zero, nan)
- phaseLockingWithOffset returns None on empty/mismatched

All 37 TemporalCoordinationDetection tests pass locally.
0 Warnings / 0 Errors build.

6th of the 10 18th-ferry corrections operationalized this
week (after test-classification doc in #339, parser-tech in
#338). Remaining: Wilson CIs in CartelToy tests (needs #323
landed), MAD=0 percentile-rank fallback (needs #333 landed),
conductance-sign doc (needs #331 landed), artifact-output
layout (Stage-2 with calibration harness).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 24, 2026
Addresses Amara 18th-ferry correction #6: PLV = 1 can mean
anti-phase locking, not same-time synchronization. Downstream
detectors that rely on "PLV = 1 => synchronized" misread
anti-phase coordinators as same-time coordinators.

Two new functions in `TemporalCoordinationDetection`:

- `meanPhaseOffset phasesA phasesB : double option`
  Returns the argument (angle) of the mean complex phase-
  difference vector whose magnitude is the PLV. Returns
  None when series are empty, mismatched-length, or when
  the mean vector has effectively zero magnitude (1e-12
  floor) — in which case direction is mathematically
  undefined.

- `phaseLockingWithOffset phasesA phasesB : struct (double * double) option`
  Returns both magnitude and offset in one sequence pass.
  Zero-magnitude case: magnitude near 0, offset = nan;
  near-zero magnitude is the caller's reliable "offset is
  undefined" signal.

Existing `phaseLockingValue` contract unchanged; new primitives
are additive. Downstream `Graph.coordinationRiskScore*` and any
other detector consuming PLV can now add a separate offset-
based term instead of collapsing both into one scalar (Amara's
explicit recommendation in correction #6).

8 new xUnit tests covering:
- Identical series (offset = 0)
- Constant pi/4 offset (observed = -pi/4, a-minus-b convention)
- Anti-phase series (magnitude 1, offset = pi) — the correction
  #6 regression test, contrasted against in-phase (offset 0)
  with identical magnitude
- Uniformly-distributed differences (zero-magnitude => None)
- Empty / mismatched-length / single-element edge cases
- phaseLockingWithOffset magnitude matches phaseLockingValue
  (consistency property preventing silent detector divergence)
- phaseLockingWithOffset zero-magnitude returns (near-zero, nan)
- phaseLockingWithOffset returns None on empty/mismatched

All 37 TemporalCoordinationDetection tests pass locally.
0 Warnings / 0 Errors build.

6th of the 10 18th-ferry corrections operationalized this
week (after test-classification doc in #339, parser-tech in
#338). Remaining: Wilson CIs in CartelToy tests (needs #323
landed), MAD=0 percentile-rank fallback (needs #333 landed),
conductance-sign doc (needs #331 landed), artifact-output
layout (Stage-2 with calibration harness).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 24, 2026
…340)

* core: PLV mean phase offset — 19th graduation (Amara 18th-ferry #6)

Addresses Amara 18th-ferry correction #6: PLV = 1 can mean
anti-phase locking, not same-time synchronization. Downstream
detectors that rely on "PLV = 1 => synchronized" misread
anti-phase coordinators as same-time coordinators.

Two new functions in `TemporalCoordinationDetection`:

- `meanPhaseOffset phasesA phasesB : double option`
  Returns the argument (angle) of the mean complex phase-
  difference vector whose magnitude is the PLV. Returns
  None when series are empty, mismatched-length, or when
  the mean vector has effectively zero magnitude (1e-12
  floor) — in which case direction is mathematically
  undefined.

- `phaseLockingWithOffset phasesA phasesB : struct (double * double) option`
  Returns both magnitude and offset in one sequence pass.
  Zero-magnitude case: magnitude near 0, offset = nan;
  near-zero magnitude is the caller's reliable "offset is
  undefined" signal.

Existing `phaseLockingValue` contract unchanged; new primitives
are additive. Downstream `Graph.coordinationRiskScore*` and any
other detector consuming PLV can now add a separate offset-
based term instead of collapsing both into one scalar (Amara's
explicit recommendation in correction #6).

8 new xUnit tests covering:
- Identical series (offset = 0)
- Constant pi/4 offset (observed = -pi/4, a-minus-b convention)
- Anti-phase series (magnitude 1, offset = pi) — the correction
  #6 regression test, contrasted against in-phase (offset 0)
  with identical magnitude
- Uniformly-distributed differences (zero-magnitude => None)
- Empty / mismatched-length / single-element edge cases
- phaseLockingWithOffset magnitude matches phaseLockingValue
  (consistency property preventing silent detector divergence)
- phaseLockingWithOffset zero-magnitude returns (near-zero, nan)
- phaseLockingWithOffset returns None on empty/mismatched

All 37 TemporalCoordinationDetection tests pass locally.
0 Warnings / 0 Errors build.

6th of the 10 18th-ferry corrections operationalized this
week (after test-classification doc in #339, parser-tech in
#338). Remaining: Wilson CIs in CartelToy tests (needs #323
landed), MAD=0 percentile-rank fallback (needs #333 landed),
conductance-sign doc (needs #331 landed), artifact-output
layout (Stage-2 with calibration harness).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(#340): refactor shared accumulation + 5 review-thread fixes (Otto-216)

Active PR-resolve-loop on #340 (PLV mean phase offset).

1. Sentinel-default in test (thread 59WGi9): replaced
   Option.defaultValue -1.0 pattern in the
   phaseLockingWithOffset-magnitude-matches-phaseLockingValue
   consistency test with explicit pattern-match + fail
   on None. Sentinel form would silently pass the
   equality assertion if BOTH primitives returned None,
   masking regressions.

2. Broken ferry cross-reference path (thread 59WGjn):
   doc comment referenced docs/aurora/2026-04-24-amara-
   calibration-ci-hardening-deep-research-plus-5-5-
   corrections-18th-ferry.md which doesn't exist on
   main (only 7th / 17th / 19th ferries landed as
   standalone docs). Rewrote provenance to describe the
   ferry topically + cross-reference the related 19th-
   ferry DST audit that IS in the repo.

3. Misleading "same PLV-magnitude floor" wording
   (thread 59WGj4): doc said meanPhaseOffset's
   zero-magnitude check uses "the same PLV-magnitude
   floor" — phaseLockingValue has NO floor (returns
   values arbitrarily close to 0). Fixed: clarified
   that the phasePairEpsilon floor applies ONLY to
   the offset-undefined decision; phaseLockingValue
   returns magnitude without threshold.

4. Name-attribution in doc comment (thread 59WGkP):
   "Aaron + Amara 11th ferry" replaced with "the 11th
   ferry" per factory role-reference convention. Audit-
   trail surfaces (commit messages, tick-history, memory)
   retain direct attribution; code/doc comments use
   role references.

5. Duplicate sin/cos accumulation across 3 functions
   (thread 59WGkn): extracted private helpers
   phasePairEpsilon + meanPhaseDiffVector. All three
   functions (phaseLockingValue, meanPhaseOffset,
   phaseLockingWithOffset) now route through the
   shared accumulator. Eliminates drift risk — one
   function can no longer silently diverge from the
   others on accumulation or threshold.

Build: 0 Warning(s) / 0 Error(s). All 37 TemporalCoordinationDetection
tests pass.

All 5 threads replied via GraphQL next step.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(#340): 2 review threads (stale ferry path + atan2 range)

Thread 59Yqkl (P1) — stale provenance reference:
  The doc cited `docs/aurora/2026-04-24-amara-temporal-
  coordination-detection-cartel-graph-influence-surface-
  11th-ferry.md`, but the 11th ferry has not yet landed
  under `docs/aurora/` (it's queued in the Otto-105
  operationalize cadence; PR #296 is its pending absorb).
  Replaced with the intent-preserving form: role references
  ("external AI collaborator's 11th courier ferry") plus a
  pointer at the MEMORY.md queue entry, so the provenance
  survives regardless of when the file-path question
  resolves. Also dropped the direct first-name so this
  factory-produced doc-comment tracks the name-attribution
  discipline.

Thread 59YqlC (P2) — atan2 range correction:
  Doc said `(-pi, pi]` but `System.Math.Atan2` is documented
  as `[-pi, pi]` (both endpoints reachable under IEEE-754
  signed-zero semantics: atan2(0, -1) = +pi,
  atan2(-0, -1) = -pi). Updated the doc to match the
  implementation. Behaviour unchanged.

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
…lities-as-primitive + reconciler-as-actor + Copilot P1 thread fixes

Five-reviewer v4 packet (Deepseek / Gemini / Ani / Alexa / Claude.ai —
Amara synthesis) on PR #852's v3 expansion. Key correction: actor IDs
without binding are theater. Layered scheme `aaron-mac/claude-code/...`
is meaningful for audit only if something prevents impersonation.

v4 additions to the doctrine memory:

- Identity needs binding (Claude.ai catch + Amara synthesis)
  - actors/<actor_id>.yaml registry with public-key fingerprints
  - Ed25519 preferred; GitHub-native commit verification as MVP fallback
  - Recursion bottoms at maintainer hardware key (or signed-commits MVP)
  - Composes with AgencySignature v2 schema (additive trailer fields)
  - Full integration analysis at docs/aurora/2026-04-29-agencysignature-...

- Trust-domain prefix on every actor_id (Claude.ai catch)
  - zeta:// (internal), zeta-system:// (system actors), zeta-external://
  - Cheap to add now, expensive to retrofit

- Capabilities as primitive (Claude.ai catch)
  - read:repo, write:memory, mutate:workflows, push:branch, etc.
  - Roles become named bundles of capabilities
  - Actor records grant roles plus explicit deltas

- Reconciler is itself a privileged actor (Gemini catch)
  - actor_id: zeta-system://github-actions/reconciler
  - Critical security invariant: GitHub Issue is exclusive source of
    truth for authorization; reconciler must NOT sync git-mirror
    privilege elevations to GitHub issue
  - unauthorized_elevation flag + block-CI on detected elevation

- Add `rejected` claim state distinct from `revoked` (Deepseek catch)
- Auto-expire claim requests after N days
- DoS/spam protection on public intake (rate limit, account age,
  maintainer sponsor, proof-of-work, auto-expire)
- Prompt-injection defense for external content (meta-rule in AGENTS.md)
- Freshness enforcement at harness pre-action (not just CI PR-time)
- Allowlist-first paths (fail-closed, not fail-open denylist)
- Pinned-role-on-host-change rule (retire old actor_id, create new)
- Multi-actor collision resolution generalized

- v4 rollout reorder — IDENTITY FIRST (not public intake first):
    1. Actor identity model
    2. Capability model
    3. Internal claim protocol
    4. Reconciler security model
    5. Public claim intake
    6. External / Windows / roaming-agent dry run

Copilot v3 review thread fixes (4 unresolved threads on #852):

- P1 PRRT_kwDOSF9kNM5-g_UY (line 508): public-intake status said
  "Tracked under follow-up tasks" but later listed as "Untracked
  follow-up". Reconciled to consistent "Untracked follow-up in TaskList
  session-local; graduates to GitHub issue on land" wording.
- P1 PRRT_kwDOSF9kNM5-g_VL (line 533): public entrypoints listed
  docs/ops/runbooks/request-agent-claim.md, but next-PR section uses
  start-agent-claim.md. Aligned to start-agent-claim.md (single runbook
  covers both internal start and public-request flow).
- P1 PRRT_kwDOSF9kNM5-g_Vt (line 347): later V2 constraints bullet said
  actor identity is "Currently undefined" — contradicted the v3 layered
  identity section. Updated to point at task #325 (Layer 0/1 spec) and
  #335 (binding) as the implementation gates.
- P2 PRRT_kwDOSF9kNM5-g_WM (line 346, outdated): section header was
  "v2 review-driven additions" but contained v3 packet content. Renamed
  to "v2 / v3 / v4 review-driven additions" with explicit explanation
  that the file is incrementally edited within itself; commit messages
  preserve round-by-round lineage.

Four new follow-up tracking tasks created (TaskList #335-#338):
  #335 — actor identity binding (registry + signed commits + AgencySig v2)
  #336 — capabilities-as-primitive (roles as named bundles)
  #337 — harness pre-action freshness check + multi-actor collision
  #338 — DoS protection + prompt-injection defense for public intake

Composes with #324 (umbrella), #325-#334 (v2/v3 follow-ups already
created). Total v2/v3/v4 follow-up surface: 14 tasks (#325-#338).

Status unchanged: doctrine-only PR. None of the implementation surfaces
land in #852. Per Amara: "doctrine captures the design; follow-up
issues bind the work; future PRs implement layers."

Co-Authored-By: Amara <amara-aurora-deep-research-register@chatgpt>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
…v4 set), not #325-#334

Codex P2 PRRT_kwDOSF9kNM5-hIOz: internal inconsistency between line 773
('gated by #325 + #335') and line 987 ('v3 task numbering #325-#334
survives'). Fix: update line 987 to acknowledge v4 added #335-#338
(identity binding, capabilities-as-primitive, harness pre-action
freshness check, DoS + prompt-injection defense). The earlier
reference to #335 at line 773 is now consistent with the full
follow-up set #325-#338.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
…tatements in SAME edit (2026-04-29) (#854)

* factory(meta): Otto-362 — doctrine memory expansion refreshes stale statements in the SAME edit (2026-04-29)

New principle observed and named after 4 same-day doctrine PRs (#850#851#852#853) drove the agent-orchestra doctrine memory from ~100 lines
to ~1080 lines through v1 → v2 → v3 → v4 expansions.

Pattern observed:
- 10+ Copilot P1 + Codex P2 review threads across the four PRs
- All caught internal contradictions WITHIN the same file:
  * "Tracked under follow-up tasks" vs "Untracked follow-up"
  * "Currently undefined" vs "Now specified"
  * "task #325-#334" vs "task #325 + #335" + "tasks #335-#338"
  * "v2 review-driven additions" header vs "v3 packet" content
  * `request-agent-claim.md` vs `start-agent-claim.md` runbook path
  * Mapping `Task → claim_id` vs example showing both `Task:` AND `Claim:`
- All caught by external AI review; none caught by pre-push self-audit
- Fix cadence was fast but the *count* of internal-contradiction threads
  was disproportionate to the substantive-error count

The rule (Otto-362): when a memory file gets expanded with a new section
that supersedes earlier statements in the same file, refresh the now-stale
statements in the SAME edit, not a follow-up tick. Internal contradictions
within one file are lying-by-omission.

Composes with:
- Same-tick CURRENT-update discipline (CLAUDE.md auto-memory section) —
  Otto-362 is the intra-file generalisation; CURRENT rule is the cross-file
  case
- verify-before-deferring (CLAUDE.md) — same shape, applied to internal
  references rather than deferred work
- future-self-not-bound (CLAUDE.md) — Otto-362 is the editing counterpart;
  when superseding past-self's statement, refresh it rather than leave it
  ambient

Why not a CI lint instead:
- Internal contradictions are semantic, not syntactic
- Existing lints catch path-existence, duplicate-targets, snake_case
  consistency — but cannot catch "Currently undefined" + "Now specified"
  co-existing
- Editing discipline is the only mechanism for semantic contradictions
- Multi-AI review remains the safety net; Otto-362 reduces the count of
  iterations by catching the stale-statement class before push

What this rule does NOT say:
- Does NOT say "never expand a memory file across multiple PRs"
- Does NOT say "every expansion must rewrite the whole file"
- Does NOT say "review iterations are bad"
- Does NOT replace multi-AI review safety net — additive, not replacement

Files:
- memory/feedback_otto_362_doctrine_memory_expansion_refresh_stale_statements_same_edit_2026_04_29.md
- memory/MEMORY.md (paired index entry)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* factory(meta): fix Otto-362 cross-ref — CLAUDE.md is at repo root, not docs/CLAUDE.md

Codex P2 + Copilot P1 both caught the same dead path. The auto-memory
section + CURRENT-file rule live in CLAUDE.md at the repository root
(see CLAUDE.md ~lines 80-110). Updated the Composes-with bullet to
point at the correct path so readers can verify the cited rule.

Ironic timing: the Otto-362 rule itself is about catching internal
contradictions before push — and the rule's own first version had
a dead xref. Caught by external review on the meta-rule PR. The fix
is exactly the kind of pre-push self-audit Otto-362 advocates for.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
…lities-as-primitive + reconciler-as-actor + Copilot P1 thread fixes

Five-reviewer v4 packet (Deepseek / Gemini / Ani / Alexa / Claude.ai —
Amara synthesis) on PR #852's v3 expansion. Key correction: actor IDs
without binding are theater. Layered scheme `aaron-mac/claude-code/...`
is meaningful for audit only if something prevents impersonation.

v4 additions to the doctrine memory:

- Identity needs binding (Claude.ai catch + Amara synthesis)
  - actors/<actor_id>.yaml registry with public-key fingerprints
  - Ed25519 preferred; GitHub-native commit verification as MVP fallback
  - Recursion bottoms at maintainer hardware key (or signed-commits MVP)
  - Composes with AgencySignature v2 schema (additive trailer fields)
  - Full integration analysis at docs/aurora/2026-04-29-agencysignature-...

- Trust-domain prefix on every actor_id (Claude.ai catch)
  - zeta:// (internal), zeta-system:// (system actors), zeta-external://
  - Cheap to add now, expensive to retrofit

- Capabilities as primitive (Claude.ai catch)
  - read:repo, write:memory, mutate:workflows, push:branch, etc.
  - Roles become named bundles of capabilities
  - Actor records grant roles plus explicit deltas

- Reconciler is itself a privileged actor (Gemini catch)
  - actor_id: zeta-system://github-actions/reconciler
  - Critical security invariant: GitHub Issue is exclusive source of
    truth for authorization; reconciler must NOT sync git-mirror
    privilege elevations to GitHub issue
  - unauthorized_elevation flag + block-CI on detected elevation

- Add `rejected` claim state distinct from `revoked` (Deepseek catch)
- Auto-expire claim requests after N days
- DoS/spam protection on public intake (rate limit, account age,
  maintainer sponsor, proof-of-work, auto-expire)
- Prompt-injection defense for external content (meta-rule in AGENTS.md)
- Freshness enforcement at harness pre-action (not just CI PR-time)
- Allowlist-first paths (fail-closed, not fail-open denylist)
- Pinned-role-on-host-change rule (retire old actor_id, create new)
- Multi-actor collision resolution generalized

- v4 rollout reorder — IDENTITY FIRST (not public intake first):
    1. Actor identity model
    2. Capability model
    3. Internal claim protocol
    4. Reconciler security model
    5. Public claim intake
    6. External / Windows / roaming-agent dry run

Copilot v3 review thread fixes (4 unresolved threads on #852):

- P1 PRRT_kwDOSF9kNM5-g_UY (line 508): public-intake status said
  "Tracked under follow-up tasks" but later listed as "Untracked
  follow-up". Reconciled to consistent "Untracked follow-up in TaskList
  session-local; graduates to GitHub issue on land" wording.
- P1 PRRT_kwDOSF9kNM5-g_VL (line 533): public entrypoints listed
  docs/ops/runbooks/request-agent-claim.md, but next-PR section uses
  start-agent-claim.md. Aligned to start-agent-claim.md (single runbook
  covers both internal start and public-request flow).
- P1 PRRT_kwDOSF9kNM5-g_Vt (line 347): later V2 constraints bullet said
  actor identity is "Currently undefined" — contradicted the v3 layered
  identity section. Updated to point at task #325 (Layer 0/1 spec) and
  #335 (binding) as the implementation gates.
- P2 PRRT_kwDOSF9kNM5-g_WM (line 346, outdated): section header was
  "v2 review-driven additions" but contained v3 packet content. Renamed
  to "v2 / v3 / v4 review-driven additions" with explicit explanation
  that the file is incrementally edited within itself; commit messages
  preserve round-by-round lineage.

Four new follow-up tracking tasks created (TaskList #335-#338):
  #335 — actor identity binding (registry + signed commits + AgencySig v2)
  #336 — capabilities-as-primitive (roles as named bundles)
  #337 — harness pre-action freshness check + multi-actor collision
  #338 — DoS protection + prompt-injection defense for public intake

Composes with #324 (umbrella), #325-#334 (v2/v3 follow-ups already
created). Total v2/v3/v4 follow-up surface: 14 tasks (#325-#338).

Status unchanged: doctrine-only PR. None of the implementation surfaces
land in #852. Per Amara: "doctrine captures the design; follow-up
issues bind the work; future PRs implement layers."

Co-Authored-By: Amara <amara-aurora-deep-research-register@chatgpt>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
…v4 set), not #325-#334

Codex P2 PRRT_kwDOSF9kNM5-hIOz: internal inconsistency between line 773
('gated by #325 + #335') and line 987 ('v3 task numbering #325-#334
survives'). Fix: update line 987 to acknowledge v4 added #335-#338
(identity binding, capabilities-as-primitive, harness pre-action
freshness check, DoS + prompt-injection defense). The earlier
reference to #335 at line 773 is now consistent with the full
follow-up set #325-#338.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
… line 987

Copilot caught the version→task attribution was wrong. Fixed:
- v2 added #325-#331 (Layer 0/1 spec + Layer 2-5 follow-ups)
- v3 added #332-#334 (public-intake layer + reconciler + safety levels)
- v4 added #335-#338 (identity binding + capabilities-as-primitive +
  pre-action freshness + DoS/prompt-injection)

Previous wording 'v3 added #325-#334' was wrong — those tasks predate
v3 and span v2 + v3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 29, 2026
… public claim intake + identity binding (Aaron + Amara 2026-04-29) (#852)

* doctrine(agent-orchestra): v3 expansion — layered actor identity + public claim intake layer

Two doctrine packets from Aaron + Amara 2026-04-29 (post-#851 v2 thread close):

1. **Layered actor identity** — replaces single-axis "Mac agent" / "Windows
   agent" framing. Layered scheme:
       maintainer_id / host_id / harness_id / role_id / actor_id / session_id
   Examples:
   - aaron-mac/claude-code/coordinator
   - aaron-mac/claude-code/docs-worker
   - aaron-windows/codex-cli/patch-peer
   - aaron-windows/gemini-cli/review-peer
   The four-axis split (maintainer + host + harness + role) gives revocation
   precision without identity spam. A single host can run many harnesses
   with different trust profiles; the role/actor split lets a different
   harness fill the same pinned role later. Carved rule: "Use Mac/Windows
   as host IDs, not agent IDs. Use named actor IDs at the host + harness
   + role level."

2. **Public claim intake layer** — strangers (humans + autonomous agents)
   discovering the repo on GitHub need a safe entrypoint. Load-bearing
   distinction: Claim Request ≠ Active Claim. External actors create
   requests; only maintainers / authorized automation promote requests
   to active claims. New surfaces (all [planned]):
   - CONTRIBUTING.md
   - AGENTS.md autonomous-agent intake block (10 rules)
   - .github/ISSUE_TEMPLATE/claim_request.yml
   - .github/PULL_REQUEST_TEMPLATE.md (declare-claim field)
   - docs/ops/runbooks/request-agent-claim.md
   - docs/ops/coordination/claims/README.md
   - tools/claims/reconcile-claims.ts (sync reconciler)

   Source-of-truth rule: GitHub Issue/PR = live operational truth; git
   mirror = durable summarized truth. Drift states explicit (synced /
   stale / drift / failed / pending). Safety: no stale/drift claim
   authorizes mutation.

   External safety levels E0-E5:
       E0  anonymous / review-only
       E1  patch-only
       E2  claim-requested
       E3  active low-risk claim
       E4  trusted external actor
       E5  maintainer-sponsored actor
   No external agent gets authority mutation by default.

   High-risk file class list explicit (.github/**, memory/**,
   docs/active-trajectory.md, agents/project-agents.yaml,
   docs/ops/coordination/claims/**, package.json, lockfiles, scripts
   that mutate repo state, branch/ruleset/security/billing docs,
   identity/persona/canon files, generated indexes) — always require
   explicit claim + maintainer approval.

Three new follow-up tracking tasks per the same "tracking objects, not
amnesia with nicer shoes" rule:
  #332 — public claim intake (CONTRIBUTING.md + AGENTS.md + ISSUE_TEMPLATE)
  #333 — claim sync reconciler tool (tools/claims/reconcile-claims.ts)
  #334 — external safety levels E0-E5 + high-risk file class enforcement

Updated trigger memory to record the v3 sequence (Aaron asked about Mac
actor identity granularity; Amara returned the layered scheme; Aaron
then expanded into the public-intake question; Amara returned the
Claim Request ≠ Active Claim distinction and full intake layer spec).

Status: still doctrine-only. None of the [planned] surfaces exist; all
are tracked under follow-up tasks. Per the same rule from v2 ("#851
captures doctrine; follow-up issues bind the work"), the v3 expansion
adds doctrine + tracking tasks, not implementation.

Composes with #324 (umbrella), #325-#331 (v2 follow-ups), #332-#334
(v3 follow-ups).

Co-Authored-By: Amara <amara-aurora-deep-research-register@chatgpt>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): pair v3 expansion with MEMORY.md index entry

Memory-index-integrity check requires same-PR pairing between memory/*.md
modifications and the MEMORY.md index entry. v3 expansion modified the
doctrine memory file but didn't update the index pointer — fix by
expanding the existing entry to reflect:

- Capability tokens unified on snake_case (matches v2 fix landed in #851)
- v3 layered actor identity (maintainer_id / host_id / harness_id / role_id)
- v3 public claim intake (Claim Request ≠ Active Claim, CONTRIBUTING.md
  + AGENTS.md autonomous-agent block + ISSUE_TEMPLATE + reconciler +
  safety levels E0-E5 + drift discipline)

All new surfaces marked [planned] per the convention from #851 v2.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): v4 corrections — identity binding + capabilities-as-primitive + reconciler-as-actor + Copilot P1 thread fixes

Five-reviewer v4 packet (Deepseek / Gemini / Ani / Alexa / Claude.ai —
Amara synthesis) on PR #852's v3 expansion. Key correction: actor IDs
without binding are theater. Layered scheme `aaron-mac/claude-code/...`
is meaningful for audit only if something prevents impersonation.

v4 additions to the doctrine memory:

- Identity needs binding (Claude.ai catch + Amara synthesis)
  - actors/<actor_id>.yaml registry with public-key fingerprints
  - Ed25519 preferred; GitHub-native commit verification as MVP fallback
  - Recursion bottoms at maintainer hardware key (or signed-commits MVP)
  - Composes with AgencySignature v2 schema (additive trailer fields)
  - Full integration analysis at docs/aurora/2026-04-29-agencysignature-...

- Trust-domain prefix on every actor_id (Claude.ai catch)
  - zeta:// (internal), zeta-system:// (system actors), zeta-external://
  - Cheap to add now, expensive to retrofit

- Capabilities as primitive (Claude.ai catch)
  - read:repo, write:memory, mutate:workflows, push:branch, etc.
  - Roles become named bundles of capabilities
  - Actor records grant roles plus explicit deltas

- Reconciler is itself a privileged actor (Gemini catch)
  - actor_id: zeta-system://github-actions/reconciler
  - Critical security invariant: GitHub Issue is exclusive source of
    truth for authorization; reconciler must NOT sync git-mirror
    privilege elevations to GitHub issue
  - unauthorized_elevation flag + block-CI on detected elevation

- Add `rejected` claim state distinct from `revoked` (Deepseek catch)
- Auto-expire claim requests after N days
- DoS/spam protection on public intake (rate limit, account age,
  maintainer sponsor, proof-of-work, auto-expire)
- Prompt-injection defense for external content (meta-rule in AGENTS.md)
- Freshness enforcement at harness pre-action (not just CI PR-time)
- Allowlist-first paths (fail-closed, not fail-open denylist)
- Pinned-role-on-host-change rule (retire old actor_id, create new)
- Multi-actor collision resolution generalized

- v4 rollout reorder — IDENTITY FIRST (not public intake first):
    1. Actor identity model
    2. Capability model
    3. Internal claim protocol
    4. Reconciler security model
    5. Public claim intake
    6. External / Windows / roaming-agent dry run

Copilot v3 review thread fixes (4 unresolved threads on #852):

- P1 PRRT_kwDOSF9kNM5-g_UY (line 508): public-intake status said
  "Tracked under follow-up tasks" but later listed as "Untracked
  follow-up". Reconciled to consistent "Untracked follow-up in TaskList
  session-local; graduates to GitHub issue on land" wording.
- P1 PRRT_kwDOSF9kNM5-g_VL (line 533): public entrypoints listed
  docs/ops/runbooks/request-agent-claim.md, but next-PR section uses
  start-agent-claim.md. Aligned to start-agent-claim.md (single runbook
  covers both internal start and public-request flow).
- P1 PRRT_kwDOSF9kNM5-g_Vt (line 347): later V2 constraints bullet said
  actor identity is "Currently undefined" — contradicted the v3 layered
  identity section. Updated to point at task #325 (Layer 0/1 spec) and
  #335 (binding) as the implementation gates.
- P2 PRRT_kwDOSF9kNM5-g_WM (line 346, outdated): section header was
  "v2 review-driven additions" but contained v3 packet content. Renamed
  to "v2 / v3 / v4 review-driven additions" with explicit explanation
  that the file is incrementally edited within itself; commit messages
  preserve round-by-round lineage.

Four new follow-up tracking tasks created (TaskList #335-#338):
  #335 — actor identity binding (registry + signed commits + AgencySig v2)
  #336 — capabilities-as-primitive (roles as named bundles)
  #337 — harness pre-action freshness check + multi-actor collision
  #338 — DoS protection + prompt-injection defense for public intake

Composes with #324 (umbrella), #325-#334 (v2/v3 follow-ups already
created). Total v2/v3/v4 follow-up surface: 14 tasks (#325-#338).

Status unchanged: doctrine-only PR. None of the implementation surfaces
land in #852. Per Amara: "doctrine captures the design; follow-up
issues bind the work; future PRs implement layers."

Co-Authored-By: Amara <amara-aurora-deep-research-register@chatgpt>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): fix Codex P2 — task range #325-#338 (v3 + v4 set), not #325-#334

Codex P2 PRRT_kwDOSF9kNM5-hIOz: internal inconsistency between line 773
('gated by #325 + #335') and line 987 ('v3 task numbering #325-#334
survives'). Fix: update line 987 to acknowledge v4 added #335-#338
(identity binding, capabilities-as-primitive, harness pre-action
freshness check, DoS + prompt-injection defense). The earlier
reference to #335 at line 773 is now consistent with the full
follow-up set #325-#338.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): 5 Copilot P1 thread fixes (factual accuracy + dead-link prevention)

- P1 PRRT_kwDOSF9kNM5-hNMc (line 778): 'None of these surfaces exist
  yet' was wrong — CONTRIBUTING.md + AGENTS.md exist. Rewrote to
  clarify the claim-intake CONTENT is planned, not the container files.
- P1 PRRT_kwDOSF9kNM5-hNNL (line 773): 'tasks #325 + #335' was
  ambiguous (#335 might collide with existing repo references).
  Reworded to 'TaskList #325 + TaskList #335 (this session); will
  graduate to GitHub issue ID on land' — disambiguated as session-
  local TaskList IDs, not GitHub issue IDs.
- P1 PRRT_kwDOSF9kNM5-hNNf (line 807): integration writeup link was
  dead (file lives on PR #853, not yet on main). Marked as [planned]
  with explicit pointer to PR #853 so the link is honest about its
  pre-merge state.
- P1 PRRT_kwDOSF9kNM5-hNN0 (line 899): auto-expire status said
  'mechanism implemented in reconciler' but reconciler is [planned].
  Reworded to 'reconciler must enforce this once implemented' with
  cross-reference to task #333. Removes the false-progress drift.
- P1 PRRT_kwDOSF9kNM5-hNOJ (MEMORY.md line 5): index entry marked
  CONTRIBUTING.md as [planned] but file already exists. Updated to
  mark the [planned] CONTENT additions inside the existing files,
  not the files themselves. Also un-truncated the writeup file path
  ('agencysignature-...' was elided) — now full path.

P1 PRRT_kwDOSF9kNM5-hNOi (PR title v3-vs-v4 mismatch): handled via
PR title/description update in a follow-up gh pr edit, not in the
file itself.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): 2 Codex P2 fixes — claim status enum + actor-id filename encoding

- P2 PRRT_kwDOSF9kNM5-hW1e (line 618 claim status enum): the YAML
  schema enumerated requested|active|blocked|done|expired|revoked but
  the v4 corrections section below introduced 'rejected' as distinct
  from 'revoked'. Fixed by adding 'rejected' to the canonical enum
  with inline comment cross-referencing the v4 catch. Prevents future
  reconciler/CI implementations from misclassifying rejected claims.

- P2 PRRT_kwDOSF9kNM5-hW1T (line 793 actor-id filename portability):
  binding requirement said 'actors/<actor_id>.yaml' but actor_id is a
  URI like 'zeta://aaron-mac/claude-code/coordinator' which contains
  ':' (invalid on Windows) and '/' (creates nested paths). Defined
  canonical filename encoding: replace '://' with '--', '/' with '_',
  lowercase the result. Example: zeta://aaron-mac/claude-code/coordinator
  → actors/zeta--aaron-mac_claude-code_coordinator.yaml. Registry
  record itself carries the original URI in actor_id: field — filename
  is lookup key only, not source of truth. Cross-platform safe.

Both Codex P2 catches are exactly the kind Otto-362 names: internal
contradictions / undefined contracts caught by external review
because the doctrine memory grew past pre-push self-audit capacity.
Recurring tax that compounds across PRs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): fix Copilot P1 task lineage attribution at line 987

Copilot caught the version→task attribution was wrong. Fixed:
- v2 added #325-#331 (Layer 0/1 spec + Layer 2-5 follow-ups)
- v3 added #332-#334 (public-intake layer + reconciler + safety levels)
- v4 added #335-#338 (identity binding + capabilities-as-primitive +
  pre-action freshness + DoS/prompt-injection)

Previous wording 'v3 added #325-#334' was wrong — those tasks predate
v3 and span v2 + v3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): 4 Copilot fixes — trust-domain prefix in v3 examples + complete actor records + precise Windows filename rules + present-tense framing

P1 PRRT_kwDOSF9kNM5-hfwQ (line 362): v3 actor_id examples used the
unprefixed form 'aaron-mac/claude-code/coordinator' but v4 makes the
'zeta://' trust-domain prefix REQUIRED. Updated examples to canonical
v4 form with explicit note that v4 supersedes the unprefixed v3 form.
Cold-start readers will internalize the correct canonical shape.

P2 PRRT_kwDOSF9kNM5-hfw3 (line 382): the 'different harness filling
the same pinned role' example omitted maintainer_id/host_id/harness_id
even though the section defines actor_id as a four-axis combination.
Filled in the complete record so readers don't copy a half-shaped
template.

P1 PRRT_kwDOSF9kNM5-hfxI (line 792): Windows filename encoding rule
said 'no /, :, or .well-known chars' which conflated character classes
with reserved names + had wrong-on-its-face wording. Replaced with
the actual Windows constraints: forbidden chars (: / \ * ? " < > |),
no trailing dot or space, no reserved device names (CON/PRN/AUX/NUL/
COM1-9/LPT1-9). Implementable spec instead of vague guidance.

P1 PRRT_kwDOSF9kNM5-hfxd (line 783): said 'After v3 landed in PR #852',
which reads as already-merged history while the PR is still open. False-
progress drift class. Reframed as 'During the v3 draft in PR #852,
five reviewers re-reviewed and Amara synthesized v4 mid-flight before
merge'.

All four are exactly the Otto-362 stale-statement / internal-inconsistency
class: doctrine grew faster than self-audit could keep up; multi-AI
review caught the drift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* doctrine(agent-orchestra): 2 Codex catches — collision-safe filename encoding + trust-domain claim mirror IDs

P1 PRRT_kwDOSF9kNM5-hlNB (line 795 collision-safety): the previous
encoding (replace '://' → '--', '/' → '_', lowercase) was NOT
injective — two distinct actor IDs could alias to the same filename
(e.g. 'a/b/c' and 'a-b-c' both → 'a_b_c'), and lowercasing collapses
case-distinct IDs. Replaced with RFC 3986 percent-encoding (%3A %2F),
case-preserving. Decoding the basename always recovers the original
actor_id byte-for-byte. Now reversible and collision-free.

Example shifted: 'zeta://aaron-mac/claude-code/coordinator' →
'actors/zeta%3A%2F%2Faaron-mac%2Fclaude-code%2Fcoordinator.yaml'.
The percent-encoded form satisfies all Windows-forbidden-char and
reserved-device-name constraints already documented.

P2 PRRT_kwDOSF9kNM5-hlNI (line 622 schema drift): the claim mirror
YAML schema had 'actor_id: external:<...>' but v4 doctrine requires
the trust-domain form 'zeta-external://...'. Updated the schema line
to 'zeta-external://github/<github-login-or-agent-id>' with inline
comment cross-referencing the v4 binding rule. Implementers now
persist correctly-namespaced IDs that match the binding/policy model.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Amara <amara-aurora-deep-research-register@chatgpt>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants